package com.example.service.impl.pc;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.common.result.Result;
import com.example.entity.dto.pc.*;
import com.example.entity.mysql.Resourcegroup;
import com.example.entity.mysql.Scheduleconfig;
import com.example.entity.mysql.Workresource;
import com.example.entity.vo.V_CKKC;
import com.example.entity.vo.pc.*;
import com.example.entity.yifei.Cmsmx;
import com.example.entity.yifei.Datelog;
import com.example.entity.yifei.Mocty;
import com.example.entity.ymlConfig.YmlConfig;
import com.example.exception.CustomException;
import com.example.mapper.MoctaMapper;
import com.example.mapper.MoctyMapper;
import com.example.mapper.pc.ScheduleMapper;
import com.example.mapper.pc.WorkresourceMapper;
import com.example.service.MoctaService;
import com.example.service.ScheduleconfigService;
import com.example.service.pc.ProductprocessresourceService;
import com.example.service.pc.ResourcegroupService;
import com.example.service.pc.ScheduleService;
import com.example.service.pc.WorkresourceService;
import com.example.untils.StringUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.DecimalFormat;
import java.util.*;

@Service
public class ScheduleServiceImpl implements ScheduleService {
    @Autowired
    private MoctyMapper moctyMapper;
    @Autowired
    private MoctaMapper moctaMapper;
    @Resource
    private ScheduleMapper scheduleMapper;
    @Resource
    private WorkresourceMapper workresourceMapper;
    @Autowired
    private ProductprocessresourceService productprocessresourceService;
    @Autowired
    private ResourcegroupService resourcegroupService;
    @Autowired
    private WorkresourceService workresourceService;
    @Autowired
    private MoctaService moctaService;
    @Autowired
    private ScheduleconfigService scheduleconfigService;
//    @Autowired
//    private InvmbService invmbService;
//    @Autowired
//    private DdgddzbService ddgddzbService;

    @Override
    public MoctaDiGui COPTDStage(String TD001, String TD002, String TD003, String startTime, String endTime, String productNo) {
        // 该销售订单所对应的工单  工单中会有重复的产品
        List<PCGongDan> moctaList = scheduleMapper.gongdan(TD001, TD002, TD003);
        if(moctaList == null || moctaList.size() == 0) {
            return null;
        }
//        ddgddzbService.list(new LambdaQueryWrapper<Ddgddzb>().eq())
        // 找到最后的成品单，如果有找到多个先直接报错
        int sum = 0;
        PCGongDan source = null;
        List<String> productIdList = new ArrayList<>();
        List<String> gdList = new ArrayList<>();
        Map<String, List<PCGongDan>> moctaMap = new HashMap<>();
        for(PCGongDan mocta : moctaList) {
            if("Y".equals(mocta.getTA011()) || "y".equals(mocta.getTA011())) mocta.setTA011("finish");
            else mocta.setTA011("normal");
//            if("1".equals(mocta.getMQ017().trim())) {   // 是自制件的   如果工单已结束，则不能修改，只读
//                ScheduleDto scheduleDto = new ScheduleDto();
//                scheduleDto.setWorkSingle(mocta.getTA001());  scheduleDto.setWorkersNumber(mocta.getTA002());
////                List<PCListVo> pcListVos = scheduleMapper.scheduleList(scheduleDto);
////                mocta.setPcData(pcListVos);
//            }
            if(mocta.getTA030().trim().equals("1")) {  // 是厂内自制的才有工序
                mocta.setPcData(getPCListVoByGD(mocta.getTA001().trim(), mocta.getTA002().trim(), startTime, endTime));
            }
            productIdList.add(mocta.getTA006().trim());
            gdList.add(mocta.getTA001().trim() + "^" + mocta.getTA002().trim());
            if(productNo.trim().equals(mocta.getTA006().trim())) {
                sum++;
                source = mocta;
            }
            List<PCGongDan> pcGongDans = moctaMap.get(mocta.getTA006().trim());
            if(pcGongDans == null) pcGongDans = new ArrayList<>();
            pcGongDans.add(mocta);
            moctaMap.put(mocta.getTA006().trim(), pcGongDans);
        }
        if(sum == 0) return null;
        if(sum > 1) {
            throw new CustomException("500", "销售订单对应的成品工单存在多笔");
        }
        Map<String, List<String>> gdMap = new HashMap<>();
        for(PCGongDan gd : moctaList) {
            gdMap.put(gd.getTA001() + gd.getTA002(), scheduleMapper.MOCTBListIsM(gd.getTA001(), gd.getTA002(), productIdList));
        }
        // 获取每一个工单生产量 对应该  销售订单的多少数量
//        List<Ddgddzb> list = ddgddzbService.list(new LambdaQueryWrapper<Ddgddzb>().eq(Ddgddzb::getTd001, TD001).eq(Ddgddzb::getTd002, TD002).eq(Ddgddzb::getTd003, TD003));
        Map<String, Double> numsMap = new HashMap<>();
//        for(Ddgddzb ddgddzb : list) {   //存入Map中
//            Double v = numsMap.get(ddgddzb.getTa001() + ddgddzb.getTd002());
//            if(v == null) v = new Double(0D);
//            v += ddgddzb.getNums();
//            numsMap.put(ddgddzb.getTa001() + ddgddzb.getTd002(), v);
//        }
        // 如果这个工单中的值在moctaList中，那么递归到下一级
        return MOCTA(source, moctaMap, gdMap, numsMap);
//        return null;
    }

    List<PCListVo> getPCListVoByGD(String TA001, String TA002, String startTime, String endTime) {
        ScheduleDto scheduleDto = new ScheduleDto();
        scheduleDto.setWorkSingle(TA001);  scheduleDto.setWorkersNumber(TA002);
        List<PCListVo> pcListVos = scheduleMapper.scheduleListNoPage(scheduleDto);
        if(pcListVos == null || pcListVos.size() == 0) return null;
        List<PcMocty> dateList = scheduleMapper.getMoctyGROUPBYDate(TA001, TA002, startTime, endTime);
        Map<String, List<NumberVo>> map = new HashMap<>();
        for(PcMocty t : dateList) {
            List<NumberVo> list = map.get(t.getTY001().trim() + t.getTY002().trim() + t.getTY019().trim());
            if(list == null) list = new ArrayList<>();
            list.add(new NumberVo(t.getDate(), t.getNums(), t.getRows(), ""));
            map.put(t.getTY001().trim() + t.getTY002().trim() + t.getTY019().trim(), list);
        }
        for(PCListVo pcListVo : pcListVos) {
            pcListVo.setNumberList(map.get(pcListVo.getWorkSingle() + pcListVo.getWorkNo() + pcListVo.getProcessNo()));
        }
        return pcListVos;
    }

    //递归工单
    MoctaDiGui MOCTA(PCGongDan gd, Map<String, List<PCGongDan>> moctaMap, Map<String, List<String>> gdMap, Map<String, Double> numsMap) {
        MoctaDiGui res = new MoctaDiGui();
        res.setWorkSingle(gd.getTA001()); res.setWorkNo(gd.getTA002()); res.setProductId(gd.getTA006()); res.setType(gd.getTA030());
//        Invmb one = invmbService.getOne(new LambdaQueryWrapper<Invmb>().eq(Invmb::getMb001, gd.getTA006()));
        res.setProductName(gd.getTA034());
        res.setStatus(gd.getTA011());
        res.setPcData(gd.getPcData());
        List<MoctaDiGui> list = new ArrayList<>();
        // 找到对应的工单
//        List<Moctb> moctbs = scheduleMapper.MOCTBListIsM(gd.getTA001(), gd.getTA002());
        List<String> moctbs = gdMap.get(gd.getTA001() + gd.getTA002());
        if(moctbs != null) {
            for(String moctb : moctbs) {
                List<PCGongDan> pcGongDans = moctaMap.get(moctb.trim());
                if(pcGongDans != null) {
                    for(PCGongDan mocta : pcGongDans) list.add(MOCTA(mocta, moctaMap, gdMap, numsMap));
                }
            }
        }
        res.setSonList(list);
        return res;
    }

    /**
     * 按销售订单 树形展示
     * @param scheduleDto
     * @return
     */
    public List<PCListVo> scheduleListNoPage(ScheduleDto scheduleDto) {
        if(StringUtils.isNotEmpty(scheduleDto.getProductSpecifications())) {
            scheduleDto.setProductSpecifications(scheduleDto.getProductSpecifications().replaceAll("([\\[\\]*+_%/^])", "/$1"));
        }
        List<PCListVo> pcListVos = scheduleMapper.scheduleListNoPage(scheduleDto);
//        System.out.println(pcListVos);
        // 拼接需要用到的，工单
        StringBuffer sb = new StringBuffer("");
        // IN ( ('5110-20230901142'), ('5120-20230901042'))
        for (PCListVo vo : pcListVos) {
            sb.append("(\'").append(vo.getWorkSingle().trim()).append("#");
            sb.append(vo.getWorkNo().trim()).append("#");
            // 工序可能是null的 直接拼接上去是错的
            if (StringUtils.isEmpty(vo.getProcessNo().trim())) sb.append("\')").append(",");
            else sb.append(vo.getProcessNo().trim()).append("\')").append(",");
            if("Y".equals(vo.getWorkStatus()) || "y".equals(vo.getWorkStatus())) vo.setWorkStatus("finish");
            else vo.setWorkStatus("normal");
        }
        if (sb.length() > 0) sb.deleteCharAt(sb.length() - 1);
//        System.out.println(sb.toString());

        ProductionStatusDto productionStatusDto = new ProductionStatusDto
                (scheduleDto.getStartTime(), scheduleDto.getEndTime(), sb.toString());
        if (StringUtils.isNotEmpty(productionStatusDto.getStrSql())) {
            List<ProductionScheduleStatusVo> mocty = scheduleMapper.getProductionScheduleStatus(productionStatusDto);
            Map<String, List<NumberVo>> map = new HashMap<>();
            // 将值放进Map中
            for (ProductionScheduleStatusVo vo : mocty) {
                NumberVo numberVo = new NumberVo(vo.getDate(), vo.getNums(), 0, "");
                StringBuffer sb2 = new StringBuffer("");
                sb2.append("(\'").append(vo.getWorkersId().trim()).append("#");
                sb2.append(vo.getWorkNo().trim()).append("#");
                // 工艺可能是null的 直接拼接上去是错的
                if (StringUtils.isEmpty(vo.getProcessNo().trim())) sb2.append("\')");
                else sb2.append(vo.getProcessNo().trim()).append("\')");
                List<NumberVo> numberVos = map.get(sb2.toString());
                if (numberVos == null) numberVos = new ArrayList<>();
                numberVos.add(numberVo);
                map.put(sb2.toString(), numberVos);
            }
            for(PCListVo vo : pcListVos) {
                StringBuffer sb2 = new StringBuffer("");
                sb2.append("(\'").append(vo.getWorkSingle().trim()).append("#");
                sb2.append(vo.getWorkNo().trim()).append("#");
                // 工艺可能是null的 直接拼接上去是错的
                if(StringUtils.isEmpty(vo.getProcessNo().trim())) sb2.append("\')");
                else sb2.append(vo.getProcessNo().trim()).append("\')");
                List<NumberVo> numberVos = map.get(sb2.toString());
                if(numberVos != null) {
                    Map<String, NumberVo> dates = new HashMap<>();
                    for(NumberVo zhi : numberVos) {
                        NumberVo v = dates.get(zhi.getDate());
                        if(v == null) v = new NumberVo(null, 0D, 0, "");
                        v.setNums(zhi.getNums() + v.getNums());
                        v.setRows(v.getRows() + 1);
                        dates.put(zhi.getDate(), v);
//                        sum += zhi.getNums();
                    }
                    List<NumberVo> listss = new ArrayList<>();
                    // 使用 forEach 循环遍历
                    dates.forEach((key, value) -> {
                        listss.add(new NumberVo(key, value.getNums(), value.getRows(), ""));
                    });
//                    vo.setScheduledNumber(sum);
                    vo.setNumberList(listss);
                }
            }
        }
//        scheduleListVo.setList(pcListVos);
        return pcListVos;
    }

    @Override
    public PageInfo<PCListVo> scheduleList(ScheduleDto scheduleDto) {
        System.out.println("COMPANY = " + YmlConfig.getYFCOMPANY());
        Scheduleconfig scheduleconfig = scheduleconfigService.getOne(new LambdaQueryWrapper<Scheduleconfig>().eq(Scheduleconfig::getCompany, YmlConfig.getYFCOMPANY()));
        if(scheduleconfig == null) {
            throw new CustomException("500", "先创建" + YmlConfig.getYFCOMPANY() + "的排产配置数据");
        }
//        ScheduleListVo scheduleListVo = new ScheduleListVo();
        if(StringUtils.isNotEmpty(scheduleDto.getProductSpecifications())) {
            scheduleDto.setProductSpecifications(scheduleDto.getProductSpecifications().replaceAll("([\\[\\]*+_%/^])", "/$1"));
        }
        if(scheduleconfig.getSchedulemode() == null || scheduleconfig.getSchedulemode().equals(1)) PageHelper.startPage(scheduleDto.getPageNum(), scheduleDto.getPageSize(),"A.CREATE_DATE DESC, B.TA003 ASC");
        else PageHelper.startPage(scheduleDto.getPageNum(), scheduleDto.getPageSize(),"A.CREATE_DATE DESC");

        List<PCListVo> pcListVos = null;
        // 读取配置表中的排产模式
        if(scheduleconfig.getSchedulemode() == null || scheduleconfig.getSchedulemode().equals(1)) pcListVos = scheduleMapper.scheduleList(scheduleDto);
        else pcListVos = scheduleMapper.scheduleListMocta(scheduleDto);

//        System.out.println(pcListVos);
        PageInfo<PCListVo> pageInfo = new PageInfo(pcListVos);
        // 拼接需要用到的，工单
        StringBuffer sb = new StringBuffer("");
        // IN ( ('5110-20230901142'), ('5120-20230901042'))
        for (PCListVo vo : pcListVos) {
            sb.append("(\'").append(vo.getWorkSingle().trim()).append("#");
            sb.append(vo.getWorkNo().trim()).append("#");
            // 工序可能是null的 直接拼接上去是错的
            if (StringUtils.isEmpty(vo.getProcessNo().trim())) sb.append("\')").append(",");
            else sb.append(vo.getProcessNo().trim()).append("\')").append(",");
        }
        if (sb.length() > 0) sb.deleteCharAt(sb.length() - 1);
//        System.out.println(sb.toString());

        ProductionStatusDto productionStatusDto = new ProductionStatusDto
                (scheduleDto.getStartTime(), scheduleDto.getEndTime(), sb.toString());
        if (StringUtils.isNotEmpty(productionStatusDto.getStrSql())) {
            List<ProductionScheduleStatusVo> mocty = scheduleMapper.getProductionScheduleStatus(productionStatusDto);
            Map<String, List<NumberVo>> map = new HashMap<>();
            // 将值放进Map中
            for (ProductionScheduleStatusVo vo : mocty) {
                NumberVo numberVo = new NumberVo(vo.getDate(), vo.getNums(), 1, vo.getUuid());
                StringBuffer sb2 = new StringBuffer("");
                sb2.append("(\'").append(vo.getWorkersId().trim()).append("#");
                sb2.append(vo.getWorkNo().trim()).append("#");
                // 工艺可能是null的 直接拼接上去是错的
                if (StringUtils.isEmpty(vo.getProcessNo().trim())) sb2.append("\')");
                else sb2.append(vo.getProcessNo().trim()).append("\')");

                List<NumberVo> numberVos = map.get(sb2.toString());
                if (numberVos == null) numberVos = new ArrayList<>();
                numberVos.add(numberVo);
                map.put(sb2.toString(), numberVos);
            }
            for(PCListVo vo : pcListVos) {
                StringBuffer sb2 = new StringBuffer("");
                sb2.append("(\'").append(vo.getWorkSingle().trim()).append("#");
                sb2.append(vo.getWorkNo().trim()).append("#");
                // 工艺可能是null的 直接拼接上去是错的
                if(StringUtils.isEmpty(vo.getProcessNo().trim())) sb2.append("\')");
                else sb2.append(vo.getProcessNo().trim()).append("\')");
                List<NumberVo> numberVos = map.get(sb2.toString().trim());
                if(numberVos != null) {
                    Map<String, NumberVo> dates = new HashMap<>();
                    for(NumberVo zhi : numberVos) {
                        NumberVo v = dates.get(zhi.getDate().trim());
                        if(v == null) v = new NumberVo(null, 0D, 0, "");
                        v.setNums(zhi.getNums() + v.getNums());
                        v.setRows(v.getRows() + 1);
                        v.setUuid(zhi.getUuid());
                        dates.put(zhi.getDate(), v);
//                        sum += zhi.getNums();
                    }
                    List<NumberVo> listss = new ArrayList<>();
                    // 使用 forEach 循环遍历
                    dates.forEach((key, value) -> {
                        listss.add(new NumberVo(key, value.getNums(), value.getRows(), value.getUuid()));
                    });
//                    vo.setScheduledNumber(sum);
                    vo.setNumberList(listss);
                }
            }
        }
//        scheduleListVo.setList(pcListVos);
        return pageInfo;
    }

    @Override
    public List<PCListVo> scheduleListExcelImport(ScheduleDto scheduleDto) {
        Scheduleconfig scheduleconfig = scheduleconfigService.getOne(new LambdaQueryWrapper<Scheduleconfig>().eq(Scheduleconfig::getCompany, YmlConfig.getYFCOMPANY()));
        if(scheduleconfig == null) {
            throw new CustomException("500", "先创建" + YmlConfig.getYFCOMPANY() + "的排产配置数据");
        }
//        ScheduleListVo scheduleListVo = new ScheduleListVo();
        if(StringUtils.isNotEmpty(scheduleDto.getProductSpecifications())) {
            scheduleDto.setProductSpecifications(scheduleDto.getProductSpecifications().replaceAll("([\\[\\]*+_%/^])", "/$1"));
        }
//        if(scheduleconfig.getSchedulemode() == null || scheduleconfig.getSchedulemode().equals(1)) PageHelper.startPage(scheduleDto.getPageNum(), scheduleDto.getPageSize(),"A.CREATE_DATE DESC, B.TA003 ASC");
//        else PageHelper.startPage(scheduleDto.getPageNum(), scheduleDto.getPageSize(),"A.CREATE_DATE DESC");

        List<PCListVo> pcListVos = null;
        // 读取配置表中的排产模式
        if(scheduleconfig.getSchedulemode() == null || scheduleconfig.getSchedulemode().equals(1)) pcListVos = scheduleMapper.scheduleList(scheduleDto);
        else pcListVos = scheduleMapper.scheduleListMocta(scheduleDto);

//        System.out.println(pcListVos);
//        PageInfo<PCListVo> pageInfo = new PageInfo(pcListVos);
        // 拼接需要用到的，工单
        StringBuffer sb = new StringBuffer("");
        // IN ( ('5110-20230901142'), ('5120-20230901042'))
        for (PCListVo vo : pcListVos) {
            sb.append("(\'").append(vo.getWorkSingle().trim()).append("#");
            sb.append(vo.getWorkNo().trim()).append("#");
            // 工序可能是null的 直接拼接上去是错的
            if (StringUtils.isEmpty(vo.getProcessNo().trim())) sb.append("\')").append(",");
            else sb.append(vo.getProcessNo().trim()).append("\')").append(",");
        }
        if (sb.length() > 0) sb.deleteCharAt(sb.length() - 1);
//        System.out.println(sb.toString());

        ProductionStatusDto productionStatusDto = new ProductionStatusDto
                (scheduleDto.getStartTime(), scheduleDto.getEndTime(), sb.toString());
        if (StringUtils.isNotEmpty(productionStatusDto.getStrSql())) {
            List<ProductionScheduleStatusVo> mocty = scheduleMapper.getProductionScheduleStatus(productionStatusDto);
            Map<String, List<NumberVo>> map = new HashMap<>();
            // 将值放进Map中
            for (ProductionScheduleStatusVo vo : mocty) {
                NumberVo numberVo = new NumberVo(vo.getDate(), vo.getNums(), 1, vo.getUuid());
                StringBuffer sb2 = new StringBuffer("");
                sb2.append("(\'").append(vo.getWorkersId().trim()).append("#");
                sb2.append(vo.getWorkNo().trim()).append("#");
                // 工艺可能是null的 直接拼接上去是错的
                if (StringUtils.isEmpty(vo.getProcessNo().trim())) sb2.append("\')");
                else sb2.append(vo.getProcessNo().trim()).append("\')");

                List<NumberVo> numberVos = map.get(sb2.toString());
                if (numberVos == null) numberVos = new ArrayList<>();
                numberVos.add(numberVo);
                map.put(sb2.toString(), numberVos);
            }
            for(PCListVo vo : pcListVos) {
                StringBuffer sb2 = new StringBuffer("");
                sb2.append("(\'").append(vo.getWorkSingle().trim()).append("#");
                sb2.append(vo.getWorkNo().trim()).append("#");
                // 工艺可能是null的 直接拼接上去是错的
                if(StringUtils.isEmpty(vo.getProcessNo().trim())) sb2.append("\')");
                else sb2.append(vo.getProcessNo().trim()).append("\')");
                List<NumberVo> numberVos = map.get(sb2.toString().trim());
                if(numberVos != null) {
                    Map<String, NumberVo> dates = new HashMap<>();
                    for(NumberVo zhi : numberVos) {
                        NumberVo v = dates.get(zhi.getDate().trim());
                        if(v == null) v = new NumberVo(null, 0D, 0, "");
                        v.setNums(zhi.getNums() + v.getNums());
                        v.setRows(v.getRows() + 1);
                        v.setUuid(zhi.getUuid());
                        dates.put(zhi.getDate(), v);
//                        sum += zhi.getNums();
                    }
                    List<NumberVo> listss = new ArrayList<>();
                    // 使用 forEach 循环遍历
                    dates.forEach((key, value) -> {
                        listss.add(new NumberVo(key, value.getNums(), value.getRows(), value.getUuid()));
                    });
//                    vo.setScheduledNumber(sum);
                    vo.setNumberList(listss);
                }
            }
        }
//        scheduleListVo.setList(pcListVos);
        return pcListVos;
    }


    @Override
    public RemainderNumsVo remainderNums(RemainderNumsDto remainderNumsDto) {
        return null;
    }

    @Override
    public UserInfoVo getUserInfo(UserInfoDto userInfoDto) {
        return null;
    }

    @Override
    public List<MaterialStatusVo> materialStatus(MaterialStatusDto materialStatusDto) {
        // 原来的代码
//        return scheduleMapper.materialStatus(materialStatusDto);

//         统率魔改
        // 1.先找到这天对应的是那个 统率的派工单号
        List<Mocty> moctyList = moctyMapper.selMoctyTongShuai(materialStatusDto.getDB(), materialStatusDto.getDH(), materialStatusDto.getDate());
        materialStatusDto.setDB(moctyList.get(0).getUdf11());
        materialStatusDto.setDH(moctyList.get(0).getUdf12());
        return scheduleMapper.materialStatusTongShuai(materialStatusDto);
    }

    @Override
    public Result updateSchedulePlanByDate(UpdateSchedulePlanDto updateSchedulePlanDto) {
        return null;
    }

    @Override
    public BalanceNumByProductIdVo getBalanceNumByProductId(BalanceNumByProductIdDto balanceNumByProductIdDto) {
        return null;
    }

    @Override
    public List<Cmsmx> getMachinesByWorkCenter(MachinesByWorkCenterDto machinesByWorkCenterDto) {
        return null;
    }

    @Override
    public List<ScheduleStatusVo> getScheduleStatus(ScheduleStatusDto scheduleStatusDto) {
        return null;
    }

    @Override
    public Result setProductLine(SetProductLineDto setProductLineDto) {
        return null;
    }

    @Override
    public List<GetProcessLineVo> getProcessLine(GetProcessLineDto getProcessLineDto) {
        return null;
    }

    @Override
    public List<Datelog> getScheduleLog(ScheduleStatusDto scheduleStatusDto) {
        return null;
    }

    // 按工单工序日期 查询[生产线/机器]
    public List<MachinesVo> selMachinesMocta(SelWorkResourceDto dto) {

        List<MoctyPlus> moctamoctyList = moctyMapper.getMoctyPlusListByTy003(dto);
        List<MachinesVo> res = new ArrayList<>();
        if(moctamoctyList.size() == 0) return res;

        List<String> moctaId = new ArrayList<>();
        List<String> moctaInfoList = new ArrayList<>();
        Map<String, Double> nowDateNumMap = new HashMap<>();  //
        if(StringUtils.isNotEmpty(dto.getDate())) {
            List<SelMoctyScheduleTypeVo> list = moctyMapper.selMoctyScheduleType(dto.getDate(), moctamoctyList);
            for(SelMoctyScheduleTypeVo t : list) {
                Double aDouble = nowDateNumMap.get(t.getTY001().trim() + t.getTY002().trim());
                if(aDouble == null) aDouble = new Double(0);
                nowDateNumMap.put(t.getTY001().trim() + t.getTY002().trim(), aDouble + t.getTY004());
                moctaInfoList.add(t.getIdid());
            }
        }
        for(MoctyPlus moctyPlus : moctamoctyList) {
//            moctaInfoList.add(moctyPlus.getTy001().trim()+moctyPlus.getTy002().trim()+moctyPlus.getProcessId().trim());
            moctaId.add(moctyPlus.getUdf05());
        }

        List<V_CKKC> ckkcList = scheduleMapper.v_ckkc();
        Map<String, Double> ckkcMap = new HashMap<>();
        for(V_CKKC t : ckkcList) ckkcMap.put(t.getMC001(), t.getMC007());
        List<MaterialStatusVo> materialStatusVoList = new ArrayList<>();
        int batchSize = 1000;
        if(moctaInfoList.size() > 0) {
            for(int i = 0; i < moctaInfoList.size(); i += batchSize) {
                int toIndex = Math.min(i + batchSize, moctaInfoList.size());
                List<MaterialStatusVo> vos = scheduleMapper.materialStatusSelMachines(moctaInfoList.subList(i, toIndex));
                materialStatusVoList.addAll(vos);
            }
        }

        Set<String> queLiaoSet = new HashSet<>(); // 把缺料的工单都算到这里来
        for(MaterialStatusVo t : materialStatusVoList) {
            Double zhi = ckkcMap.get(t.getProductId().trim());
            if(zhi == null) continue;
            if(zhi < t.getUnReceivedNums()) {
                queLiaoSet.add(t.getWorkSingle().trim() + t.getWorkNo().trim());
            }
        }

        List<Workresource> son = workresourceMapper.sellist(moctaId);
        Map<String, List<Workresource>> workresourceMap = new HashMap<>();
        Set<Integer> set = new HashSet<>();  set.add(1);  set.add(2); set.add(3); set.add(4);
        for(Workresource t : son) {
            List<Workresource> workresources = workresourceMap.get(t.getProductLineId().trim());
            if(workresources == null) workresources = new ArrayList<>();
            workresources.add(t);
            workresourceMap.put(t.getProductLineId().trim(), workresources);
            if(t.getResourceGroupId() != null) set.add(t.getResourceGroupId());
            if(t.getResourceId() != null) set.add(t.getResourceId());
        }
        List<Integer> ids = new ArrayList<>();
        for(Integer s : set) ids.add(s);
        List<Resourcegroup> groups = resourcegroupService.list(new LambdaQueryWrapper<Resourcegroup>().in(Resourcegroup::getResourceGroupId, ids));   // 全部的resourcegroup表内容
        Map<Integer, Resourcegroup> posMap = new HashMap<>();
        for(Resourcegroup tt : groups) {
            posMap.put(tt.getResourceGroupId(), tt);
        }

        for(MoctyPlus t : moctamoctyList) {
            List<Workresource> a = new ArrayList<>();
            String mouldGroupNo = "";
            String mouldGroupName = "";
            // 将对应的机器，塞入到排产单里面去。
            List<Workresource> workresources = workresourceMap.get(t.getUdf05().trim());
            if(workresources != null) {
                for(Workresource workresource : workresources) {
                    // 将数据用生产线编号分组
                    Resourcegroup one = posMap.get(workresource.getResourceGroupId());
                    if(one == null) continue;
//                    Resourcegroup one = resourcegroupService.getOne(new LambdaQueryWrapper<Resourcegroup>()
//                            .eq(Resourcegroup::getResourceGroupId, workresource.getResourceGroupId()));
                    workresource.setResourceGroupNO(one.getResourceGroupNO());
                    workresource.setResourceGroupName(one.getResourceGroupName());
                    // 找出资源组的根节点编号
                    Integer originIdById = workresource.getResourceTypeId();
                    Resourcegroup parent = posMap.get(originIdById);
                    workresource.setResourceTypeId(originIdById);
                    workresource.setResourceTypeNO(parent.getResourceGroupNO());
                    workresource.setResourceTypeName(parent.getResourceGroupName());
                    if(originIdById.equals(3)) {
                        mouldGroupNo = one.getResourceGroupNO();
                        mouldGroupName = one.getResourceGroupName();
                    }
                    if(workresource.getResourceId() != null) {
                        Resourcegroup one1 = posMap.get(workresource.getResourceId());
//                        Resourcegroup one1 = resourcegroupService.getOne(new LambdaQueryWrapper<Resourcegroup>()
//                                .eq(Resourcegroup::getResourceGroupId, workresource.getResourceId()));
                        if(one1 != null) {
                            workresource.setResourceNO(one1.getResourceGroupNO());
                            workresource.setResourceName(one1.getResourceGroupName());
                        }
                    }
                    a.add(workresource);
                }
            }
            Resourcegroup one = null;
            if(StringUtils.isEmpty(t.getTy009()) || "****".equals(t.getTy009().trim())) one = null;
            else one = posMap.get(Integer.parseInt(t.getTy009().trim()));

//            List<MaterialStatusVo> materialStatusVos = scheduleMapper.materialStatus(new MaterialStatusDto(t.getTy004(), t.getTy001(), t.getTy002(), t.getProcessId()));
            Boolean flag = false;
            if(queLiaoSet.contains(t.getTy001().trim()+t.getTy002().trim())) {
                flag = true;
            }
//            for(MaterialStatusVo xx : materialStatusVos) {
//                if(StringUtils.isNotEmpty(xx.getMattype()) && "1".equals(xx.getMattype().trim()) && xx.getUnReceivedNums() > xx.getStockNums()) {
//                    flag = true; break;
//                }
//            }

            MachinesVo vo = new MachinesVo(nowDateNumMap.get(t.getTy001().trim() + t.getTy002().trim()), t.getOp_seq(), t.getToop_seq(), mouldGroupNo, mouldGroupName, t.getJitaizhipaishijian(), t.getSaleOrderNum(), t.getProcessrouteName(), t.getProcessName(),
                    t.getCustomName(), flag, t.getDeliveryDate(), t.getOrderSingle(), t.getOrderNo(), t.getInvrt_name(), t.getProcessroute(), t.getInv_no(), t.getTy019(),
                    t.getProcessId(), t.getMocStatus(), t.getWorkCenterId(), t.getWorkCenterName(),
                    t.getTy001(), t.getTy002(), t.getProductId(), t.getProductName(), t.getSpecification(), t.getTy003(), t.getUdf05(), t.getTy009(), one == null ? "" : one.getResourceGroupName(),
                    one == null ? "" : one.getResourceGroupNO(), t.getTy004(), t.getUdf03(), null, a);
            res.add(vo);
        }
        // 算一下负荷
        for(MachinesVo t : res) {
            for(Workresource workresource : t.getList()) {
                if(workresource.getResourceTypeId().equals(1) || workresource.getResourceTypeId().equals(2)) {  // 找出机器或生产线，塞入负载情况。
                    if(workresource.getBeat() != null && workresource.getBeat() > 0) {
                        Double v = new Double(t.getNums() * workresource.getBeat() / 3600);
                        DecimalFormat df = new DecimalFormat("#.######"); // 保留6位小数 String formatted = df.format(number);
                        t.setLoadTime(df.format(v));
                    }else{
                        if(workresource.getQuota() != null && workresource.getQuota() > 0) {
                            Double v = new Double(t.getNums() / workresource.getQuota());
                            DecimalFormat df = new DecimalFormat("#.######"); // 保留6位小数 String formatted = df.format(number);
                            t.setLoadTime(df.format(v));
                        }
                    }
                    break;
                }
            }
        }
        return res;
    }

    @Override
    public List<MaterialStatusVo> materialStatusTongShuai(MaterialStatusDto materialStatusDto) {
        return null;
    }

    // 按工单工序日期 查询[生产线/机器]
    @Override
    public List<MachinesVo> selMachines(SelWorkResourceDto dto) {

//        List<MOCTA> moctaList = moctaMapper.getMoctaFromMocty(dto.getDate());

        List<MoctyPlus> list = moctyMapper.getMoctyPlusListYuan(dto);

        List<MachinesVo> res = new ArrayList<>();
        if(list.size() == 0) return res;
        List<Resourcegroup> groups = resourcegroupService.list();   // 全部的resourcegroup表内容
//        List<Resourcegroup> groups = resourcegroupService.getResourceGroupListFromRedis(); // 全部的resourcegroup表内容
        Map<Integer, Resourcegroup> posMap = new HashMap<>();
        for(Resourcegroup tt : groups) {
            posMap.put(tt.getResourceGroupId(), tt);
        }

        LambdaQueryWrapper<Workresource> workresourceLambdaQueryWrapper = new LambdaQueryWrapper<Workresource>()
                .orderByAsc(Workresource::getCreateTime);
        if(StringUtils.isNotEmpty(dto.getWorkSingle())) workresourceLambdaQueryWrapper.eq(Workresource::getWorkSingle, dto.getWorkSingle());
        if(StringUtils.isNotEmpty(dto.getWorkNo())) workresourceLambdaQueryWrapper.eq(Workresource::getWorkNo, dto.getWorkNo());
        if(StringUtils.isNotEmpty(dto.getDate())) workresourceLambdaQueryWrapper.eq(Workresource::getDate, dto.getDate());
        if(StringUtils.isNotEmpty(dto.getProcessNo())) workresourceLambdaQueryWrapper.eq(Workresource::getProcessNo, dto.getProcessNo());
        if(StringUtils.isNotEmpty(dto.getProcessId())) workresourceLambdaQueryWrapper.eq(Workresource::getProcessId, dto.getProcessId());

        List<Workresource> son = workresourceService.list(workresourceLambdaQueryWrapper);
        for(MoctyPlus t : list) {

            List<Workresource> a = new ArrayList<>();
            for(Workresource workresource : son) {   // 将对应的机器，塞入到排产单里面去。
                // 将数据用生产线编号分组
                if(t.getUdf05().trim().equals(workresource.getProductLineId().trim())) {
                    Resourcegroup one = posMap.get(workresource.getResourceGroupId());
                    if(one == null) continue;
//                    Resourcegroup one = resourcegroupService.getOne(new LambdaQueryWrapper<Resourcegroup>()
//                            .eq(Resourcegroup::getResourceGroupId, workresource.getResourceGroupId()));
                    workresource.setResourceGroupNO(one.getResourceGroupNO());
                    workresource.setResourceGroupName(one.getResourceGroupName());
                    // 找出资源组的根节点编号
                    Integer originIdById = resourcegroupService.getOriginIdById(workresource.getResourceGroupId(), posMap);
                    Resourcegroup parent = posMap.get(originIdById);
//                    Resourcegroup parent = resourcegroupService.getOne(new LambdaQueryWrapper<Resourcegroup>()
//                            .eq(Resourcegroup::getResourceGroupId, originIdById));
                    workresource.setResourceTypeId(originIdById);
                    workresource.setResourceTypeNO(parent.getResourceGroupNO());
                    workresource.setResourceTypeName(parent.getResourceGroupName());
                    if(workresource.getResourceId() != null) {
                        Resourcegroup one1 = posMap.get(workresource.getResourceId());
//                        Resourcegroup one1 = resourcegroupService.getOne(new LambdaQueryWrapper<Resourcegroup>()
//                                .eq(Resourcegroup::getResourceGroupId, workresource.getResourceId()));
                        if(one1 != null) {
                            workresource.setResourceNO(one1.getResourceGroupNO());
                            workresource.setResourceName(one1.getResourceGroupName());
                        }
                    }
                    a.add(workresource);
                }
            }
            Resourcegroup one = null;
            if(StringUtils.isEmpty(t.getTy009()) || "****".equals(t.getTy009().trim())) one = null;
            else one = posMap.get(Integer.parseInt(t.getTy009().trim()));
//            Resourcegroup one = resourcegroupService.getOne(new LambdaQueryWrapper<Resourcegroup>().eq(Resourcegroup::getResourceGroupId, t.getTy009()));

            List<MaterialStatusVo> materialStatusVos = materialStatus(new MaterialStatusDto(t.getTy004(), t.getTy001(), t.getTy002(), t.getProcessId(), null));
            Boolean flag = false;
            for(MaterialStatusVo xx : materialStatusVos) {
                if(xx.getUnReceivedNums() > xx.getStockNums()) {
                    flag = true; break;
                }
            }

            MachinesVo vo = new MachinesVo(null, null, null, null, null, null,null,null, null, null, flag, t.getDeliveryDate(), t.getOrderSingle(), t.getOrderNo(), t.getInvrt_name(), t.getProcessroute(), t.getInv_no(), t.getTy019(), t.getProcessId(), t.getMocStatus(), t.getWorkCenterId(), t.getWorkCenterName(),
                    t.getTy001(), t.getTy002(), t.getProductId(), t.getProductName(), t.getSpecification(), t.getTy003(), t.getUdf05(), t.getTy009(), one == null ? "" : one.getResourceGroupName(),
                    one == null ? "" : one.getResourceGroupNO(), t.getTy004(), t.getUdf03(), null, a);
            res.add(vo);
        }
        // 算一下负荷
        for(MachinesVo t : res) {
            for(Workresource workresource : t.getList()) {
                if(workresource.getResourceTypeId().equals(1) || workresource.getResourceTypeId().equals(2)) {  // 找出机器或生产线，塞入负载情况。
                    if(workresource.getBeat() != null && workresource.getBeat() > 0) {
                        Double v = new Double(t.getNums() * workresource.getBeat() / 3600);
                        DecimalFormat df = new DecimalFormat("#.######"); // 保留6位小数 String formatted = df.format(number);
                        t.setLoadTime(df.format(v));
                    }else{
                        if(workresource.getQuota() != null && workresource.getQuota() > 0) {
                            Double v = new Double(t.getNums() / workresource.getQuota());
                            DecimalFormat df = new DecimalFormat("#.######"); // 保留6位小数 String formatted = df.format(number);
                            t.setLoadTime(df.format(v));
                        }
                    }
                    break;
                }
            }
        }
        return res;
    }


    @Override
    public List<MachinesVo> selMachinesChaKanPaiChanStatus(SelWorkResourceDto dto) {

//        List<MOCTA> moctaList = moctaMapper.getMoctaFromMocty(dto.getDate());

        List<MoctyPlus> list = moctyMapper.getMoctyPlusListYuan(dto);

        List<MachinesVo> res = new ArrayList<>();
        if(list.size() == 0) return res;
        List<Resourcegroup> groups = resourcegroupService.list();   // 全部的resourcegroup表内容
//        List<Resourcegroup> groups = resourcegroupService.getResourceGroupListFromRedis(); // 全部的resourcegroup表内容
        Map<Integer, Resourcegroup> posMap = new HashMap<>();
        for(Resourcegroup tt : groups) {
            posMap.put(tt.getResourceGroupId(), tt);
        }

        LambdaQueryWrapper<Workresource> workresourceLambdaQueryWrapper = new LambdaQueryWrapper<Workresource>()
                .orderByAsc(Workresource::getCreateTime);
        if(StringUtils.isNotEmpty(dto.getWorkSingle())) workresourceLambdaQueryWrapper.eq(Workresource::getWorkSingle, dto.getWorkSingle());
        if(StringUtils.isNotEmpty(dto.getWorkNo())) workresourceLambdaQueryWrapper.eq(Workresource::getWorkNo, dto.getWorkNo());
        if(StringUtils.isNotEmpty(dto.getDate())) workresourceLambdaQueryWrapper.eq(Workresource::getDate, dto.getDate());
        if(StringUtils.isNotEmpty(dto.getProcessNo())) workresourceLambdaQueryWrapper.eq(Workresource::getProcessNo, dto.getProcessNo());
        if(StringUtils.isNotEmpty(dto.getProcessId())) workresourceLambdaQueryWrapper.eq(Workresource::getProcessId, dto.getProcessId());

        List<Workresource> son = workresourceService.list(workresourceLambdaQueryWrapper);
        for(MoctyPlus t : list) {

            List<Workresource> a = new ArrayList<>();
            for(Workresource workresource : son) {   // 将对应的机器，塞入到排产单里面去。
                // 将数据用生产线编号分组
                if(t.getUdf05().trim().equals(workresource.getProductLineId().trim())) {
                    Resourcegroup one = posMap.get(workresource.getResourceGroupId());
                    if(one == null) continue;
//                    Resourcegroup one = resourcegroupService.getOne(new LambdaQueryWrapper<Resourcegroup>()
//                            .eq(Resourcegroup::getResourceGroupId, workresource.getResourceGroupId()));
                    workresource.setResourceGroupNO(one.getResourceGroupNO());
                    workresource.setResourceGroupName(one.getResourceGroupName());
                    // 找出资源组的根节点编号
                    Integer originIdById = resourcegroupService.getOriginIdById(workresource.getResourceGroupId(), posMap);
                    Resourcegroup parent = posMap.get(originIdById);
//                    Resourcegroup parent = resourcegroupService.getOne(new LambdaQueryWrapper<Resourcegroup>()
//                            .eq(Resourcegroup::getResourceGroupId, originIdById));
                    workresource.setResourceTypeId(originIdById);
                    workresource.setResourceTypeNO(parent.getResourceGroupNO());
                    workresource.setResourceTypeName(parent.getResourceGroupName());
                    if(workresource.getResourceId() != null) {
                        Resourcegroup one1 = posMap.get(workresource.getResourceId());
//                        Resourcegroup one1 = resourcegroupService.getOne(new LambdaQueryWrapper<Resourcegroup>()
//                                .eq(Resourcegroup::getResourceGroupId, workresource.getResourceId()));
                        if(one1 != null) {
                            workresource.setResourceNO(one1.getResourceGroupNO());
                            workresource.setResourceName(one1.getResourceGroupName());
                        }
                    }
                    a.add(workresource);
                }
            }
            Resourcegroup one = null;
            if(StringUtils.isEmpty(t.getTy009()) || "****".equals(t.getTy009().trim())) one = null;
            else one = posMap.get(Integer.parseInt(t.getTy009().trim()));
//            Resourcegroup one = resourcegroupService.getOne(new LambdaQueryWrapper<Resourcegroup>().eq(Resourcegroup::getResourceGroupId, t.getTy009()));

//            List<MaterialStatusVo> materialStatusVos = materialStatus(new MaterialStatusDto(t.getTy004(), t.getTy001(), t.getTy002(), t.getProcessId(), null));
//            Boolean flag = false;
//            for(MaterialStatusVo xx : materialStatusVos) {
//                if(xx.getUnReceivedNums() > xx.getStockNums()) {
//                    flag = true; break;
//                }
//            }

            MachinesVo vo = new MachinesVo(null, null, null, null, null, null,null,null, null, null, null, t.getDeliveryDate(), t.getOrderSingle(), t.getOrderNo(), t.getInvrt_name(), t.getProcessroute(), t.getInv_no(), t.getTy019(), t.getProcessId(), t.getMocStatus(), t.getWorkCenterId(), t.getWorkCenterName(),
                    t.getTy001(), t.getTy002(), t.getProductId(), t.getProductName(), t.getSpecification(), t.getTy003(), t.getUdf05(), t.getTy009(), one == null ? "" : one.getResourceGroupName(),
                    one == null ? "" : one.getResourceGroupNO(), t.getTy004(), t.getUdf03(), null, a);
            res.add(vo);
        }
        // 算一下负荷
        for(MachinesVo t : res) {
            for(Workresource workresource : t.getList()) {
                if(workresource.getResourceTypeId().equals(1) || workresource.getResourceTypeId().equals(2)) {  // 找出机器或生产线，塞入负载情况。
                    if(workresource.getBeat() != null && workresource.getBeat() > 0) {
                        Double v = new Double(t.getNums() * workresource.getBeat() / 3600);
                        DecimalFormat df = new DecimalFormat("#.######"); // 保留6位小数 String formatted = df.format(number);
                        t.setLoadTime(df.format(v));
                    }else{
                        if(workresource.getQuota() != null && workresource.getQuota() > 0) {
                            Double v = new Double(t.getNums() / workresource.getQuota());
                            DecimalFormat df = new DecimalFormat("#.######"); // 保留6位小数 String formatted = df.format(number);
                            t.setLoadTime(df.format(v));
                        }
                    }
                    break;
                }
            }
        }
        return res;
    }
    // 工单绑定机器
}
